#!/bin/bash

sonarScannerBin="/root/.jenkins/tools/hudson.plugins.sonar.SonarRunnerInstallation/sonar-scanner/bin/sonar-scanner"
sonarHostUrl="http://xxx.xxx.com"
checkTaskStatusUrl="$sonarHostUrl/api/ce/component?componentKey="
checkSonarResultUrl="$sonarHostUrl/api/qualitygates/project_status?projectKey="
loginToken="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
authorizationToken="Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
projectName=$1
projectBaseDir=$2
projectLanguage="java"
projectVersion="1.0"
sourceEncoding=UTF-8

RETRY_TIMES=0
MAX_RETRY_TIMES=300
POINTS_COUNT=1
POINTS="."

function checkTaskStatus() {
	if [[ $RETRY_TIMES -gt $MAX_RETRY_TIMES ]];then
    echo "ERROR: Invalid response message: $1"
		exit 1
	elif [[ $POINTS_COUNT -gt 10 ]];then
		POINTS_COUNT=1
		POINTS="."
  fi

	echo "INFO: Pulling the sonarQube analysis job execute status$POINTS"
  result=$(curl -s -X GET -H "Authorization: $authorizationToken" "$checkTaskStatusUrl$projectName")
	#echo "DEBUG: Get reponse message: $result"

	# 先判断返回结果是否是我们想要的结果,必须至少包含errors、queue、current中的一个,如果不包含则sleep 1秒后重试
	if [[ ! ($result =~ "errors" || $result =~ "queue" || $result =~ "current") ]];then
		sleep 1
		RETRY_TIMES=`expr $RETRY_TIMES + 1`
		POINTS_COUNT=`expr $POINTS_COUNT + 1`
		POINTS=".$POINTS"
		checkTaskStatus $result
		return
	fi

	# 如果返回结果包含字符errors,那么为失败则打印错误信息并停止
	if [[ $result =~ "errors" ]];then
		if [[ $result =~ "msg" ]];then
			errorMsg=$(echo $result | jq -r '.errors[0].msg')
		else
			errorMsg=$(echo $result | jq -r '.errors')
		fi
		echo "ERROR: SonarQube $errorMsg"
		exit 1
	fi

	# 如果返回结果不包含current字符，那么代表当前有正在进行的，需要等待，sleep 1秒后重新执行方法
	if [[ ! ($result =~ "current") ]];then
		sleep 1
		RETRY_TIMES=`expr $RETRY_TIMES + 1`
		POINTS_COUNT=`expr $POINTS_COUNT + 1`
		POINTS=".$POINTS"
		checkTaskStatus $result
		return
	fi

	# 如果返回结果包含字符queue字符，那么检查queue的数组数量，如果不为0则表示有正在进行的也需要等待，sleep 1秒后重新执行方法
	if [[ $result =~ "queue" ]];then
		queue=$(echo $result | jq '.queue')
		if [[ $queue != "[]" ]];then
      sleep 1
			RETRY_TIMES=`expr $RETRY_TIMES + 1`
			POINTS_COUNT=`expr $POINTS_COUNT + 1`
			POINTS=".$POINTS"
			checkTaskStatus $result
			return
    fi
	fi

	# 如果都校验通过则获取当前状态，判断是否是SUCCESS，如果是则认为通过则查询分析结果，如果不是则判断是否是FAILED，如果是则不通过否则sleep 1秒后重新执行方法
	status=$(echo $result | jq -r '.current.status')
	if [[ $status == "SUCCESS" ]];then
		echo "INFO: SonarQube analysis job execute status: $status"
	elif [[ $status == "FAILED" ]];then
		echo "ERROR: SonarQube analysis job execute status: $status"
		echo "ERROR: SonarQube analysis job failed to execute!"
		exit 1
	else
		sleep 1
    RETRY_TIMES=`expr $RETRY_TIMES + 1`
    POINTS_COUNT=`expr $POINTS_COUNT + 1`
    POINTS=".$POINTS"
    checkTaskStatus $result
    return
	fi
}

function checkSonarResult() {
	if [[ $RETRY_TIMES -gt $MAX_RETRY_TIMES ]];then
    echo "ERROR: Invalid response message: $1"
    exit 1
  elif [[ $POINTS_COUNT -gt 10 ]];then
    POINTS_COUNT=1
    POINTS="."
  fi

	echo "INFO: Pulling the sonarQube analysis results$POINTS"
  result=$(curl -s -X GET -H "Authorization: $authorizationToken" "$checkSonarResultUrl$projectName")
  #echo "DEBUG: Get reponse message: $result"

	if [[ $result =~ "projectStatus" && $result =~ "status" ]];then
		status=$(echo $result | jq -r '.projectStatus.status')
		if [[ $status == "OK" ]];then
      echo "INFO: SonarQube analysis result: $status"
			echo "INFO: SonarQube quality passed"
    else
      echo "ERROR: SonarQube analysis result: $status"
      echo "ERROR: SonarQube quality not passed!"
      exit 1
		fi
	else
		sleep 1
    RETRY_TIMES=`expr $RETRY_TIMES + 1`
    POINTS_COUNT=`expr $POINTS_COUNT + 1`
    POINTS=".$POINTS"
    checkSonarResult $result
    return
	fi
}

function start() {

	# 扫描并上传
	$sonarScannerBin scan -Dsonar.host.url=$sonarHostUrl -Dsonar.login=$loginToken -Dsonar.projectName=$projectName -Dsonar.language=$projectLanguage -Dsonar.projectVersion=$projectVersion -Dsonar.sourceEncoding=$sourceEncoding -Dsonar.projectKey=$projectName -Dsonar.java.binaries=$projectBaseDir -Dsonar.sources=$projectBaseDir -Dsonar.projectBaseDir=$projectBaseDir

	# 检查任务状态
	checkTaskStatus

	POINTS_COUNT=1
	POINTS="."

	# 检查sonar结果
	checkSonarResult
}

start